package com.zzgc.modules.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zzgc.common.entity.AuthUser;
import com.zzgc.common.entity.School;
import com.zzgc.common.entity.Student;
import com.zzgc.common.entity.StudentArchives;
import com.zzgc.common.response.HttpStatus;
import com.zzgc.common.response.Result;
import com.zzgc.common.utils.*;
import com.zzgc.modules.param.AddStudentParam;
import com.zzgc.modules.param.ExportStudentTemplate;
import com.zzgc.modules.param.ImportStudentTemplate;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.core.io.FileUrlResource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.ParseException;
import java.time.LocalDate;
import java.util.*;

/**
 * 学生管理
 *
 * @Author:
 * @CreateTime: 2022-11-21  17:19
 * @Description:
 * @Version: 1.0
 */
@RestController
@RequestMapping("student")
@Api(tags = "学生管理")
public class StudentController extends BaseController {

    @GetMapping("getList")
    @ApiOperation(value = "根据条件查询学生", notes = "列表展示, 查询学生信息")
    public Result getStudents(Student student) {
        if (super.getUserRole() != null && !super.getUserRole().equals("5")) {
            throw new RuntimeException("权限不足,您不是学校管理员!");
        }
        student.setSSchoolId(Long.valueOf(super.getSchoolId()));
        List<Student> students = studentService.queryByPage(student);
        HashMap<String, Object> map = new HashMap<>();
        map.put("total", students.size() == 0 ? 0 : students.get(0).getTotal());
        map.put("data", students);
        super.getBankStatus();
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg(HttpStatus.OK.getReasonPhrase())
                .data(map)
                .build();
    }

    @PostMapping("add")
    @ApiOperation(value = "添加单个学生信息", notes = "添加")
    public Result addStudent(@Validated @RequestBody Student student) {
        if (super.getUserRole() != null && !super.getUserRole().equals("5")) {
            throw new RuntimeException("只能学校管理员添加!");
        }
        // 添加表名
        // student.setTableName(super.getStudentTable());
        // 添加生日
        try {
            student.setSBirthday(IdCardNumberMethod.getBirthDayFromIdCard(student.getSIdCard()));
        } catch (ParseException e) {
            throw new RuntimeException("识别身份证: " + student.getSIdCard() + "获取生日失败!");
        }
        // 判断身份证号是否重复
        Student student2 = new Student();
        student2.setSYear(getsYear() + "");
        student2.setSIdCard(student.getSIdCard());
        if (studentService.count(student2) > 0) {
            return Result.builder().code(500).msg("身份证号已存在!").build();
        }
        // 添加时间
        student.setSCreateDate(new Date());
        student.setSCreateBy(super.getUserName());
        // 添加学校Id
        student.setSSchoolId(Long.valueOf(super.getSchoolId()));
        // ===============  给省级发送学生数据获取唯一id ==============
        AddStudentParam addStudentParam = new AddStudentParam();
        addStudentParam.setSClassName(schoolGradeClassService.queryById(student.getSClassId()).getSName());
        addStudentParam.setSGradeName(schoolGradeService.queryById(student.getSGradeId()).getSName());
        addStudentParam.setSIdCard(student.getSIdCard());
        addStudentParam.setSMobile(student.getSMobile());
        addStudentParam.setSName(student.getSName());
        addStudentParam.setSBirthday(student.getSBirthday());
        addStudentParam.setSOkMirror(student.getSOkMirror());
        addStudentParam.setSSex(student.getSSex());
        addStudentParam.setSStudentNum(student.getSStudentNum());
        School school = schoolService.queryById(Long.valueOf(super.getSchoolId()));
        school.setSArea(super.getUserRegionId());
        school.setSYear(getsYear() + "");
        addStudentParam.setSchool(school);
        AuthUser user = userService.queryById(Long.valueOf(super.getUserId()));
        addStudentParam.setUser(user);
        System.out.println("addStudentParam = " + addStudentParam);
        String s = HttpClientUtil.doPost(portUrl + "vision/receive/addStudent", addStudentParam);
        Result result = JSON.parseObject(s, Result.class);
        System.out.println("result = " + result);
        if (result.getCode() == 200) {
            Long studentId = Long.valueOf(result.getData().toString());
            student.setSStudentId(studentId);
        }
        // 开始添加学生
        studentService.insert(student);
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg(HttpStatus.OK.getReasonPhrase())
                .data(student)
                .build();
    }

    @GetMapping("getById/{studentId}")
    @ApiOperation(value = "根据学生ID获取信息", notes = "修改单个学生用, 获取学生信息")
    public Result getByIdStudent(@PathVariable("studentId") Long studentId) {
        Student student = studentService.queryById(studentId);
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg(HttpStatus.OK.getReasonPhrase())
                .data(student)
                .build();
    }

    @PutMapping("edit")
    @ApiOperation(value = "编辑学生信息", notes = "修改学生信息")
    public Result editStudent(@Validated @RequestBody Student student) {
        if (super.getUserRole() != null && !super.getUserRole().equals("5")) {
            throw new RuntimeException("权限不足,您不是学校管理员!");
        }
        try {// 如改变身份证号 生日需要更新
            student.setSBirthday(IdCardNumberMethod.getBirthDayFromIdCard(student.getSIdCard()));
        } catch (ParseException e) {
            return Result.builder().code(500).msg("生日自动获取失败!请检查身份证号是否正确!").build();
        }

        Student student2 = studentService.queryById(student.getId());
        // 如果修改身份证
        if (!student2.getSIdCard().equals(student.getSIdCard())) {
            Student student3 = new Student();
            student3.setSYear(getsYear() + "");
            student3.setSIdCard(student.getSIdCard());
            if (studentService.count(student3) > 0) {
                return Result.builder().code(500).msg("身份证号已存在!").build();
            }
        }
        Student student1 = studentService.update(student);
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg(HttpStatus.OK.getReasonPhrase())
                .data(student1)
                .build();
    }

    @DeleteMapping("del/{studentId}")
    @ApiOperation(value = "删除学生信息", notes = "删除")
    public Result deleteStudent(@PathVariable("studentId") Long studentId) {
        boolean b = studentService.deleteById(studentId);
        if (!b) {
            return Result.builder().code(500).msg("删除失败!").build();
        }
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg("删除成功!")
                .build();
    }

    //@SneakyThrows
    @PostMapping("importStudentXls")
    @ApiOperation(value = "导入学生信息表", notes = "导入的Excel表")
    @Transactional
    public Result importStudentXls(@RequestPart("file") MultipartFile file) throws IOException {
        if (super.getUserRole() != null && !super.getUserRole().equals("5")) {
            throw new RuntimeException("只能学校管理员添加!");
        }
        List<ImportStudentTemplate> studentTemplateList = new ArrayList<>();
        // 设置预览多个工作表
        int i = 0;
        for (; ; ) {
            // 读取表格
            List<ImportStudentTemplate> objects = EasyExcel.read(file.getInputStream())
                    .head(ImportStudentTemplate.class)
                    .sheet(i++)
                    .doReadSync();
            // 如果为0就是没有数据了, 结束循环
            if (objects.size() == 0) {
                break;
            }
            studentTemplateList.addAll(objects);
        }
        // 开始上传到上级服务
        Map<String, Object> hashMap = new HashMap<>();
        School school = schoolService.queryById(Long.valueOf(super.getSchoolId()));
        AuthUser user = userService.queryById(Long.valueOf(super.getUserId()));
        school.setSArea(super.getUserRegionId());
        school.setSYear(getsYear() + "");
        hashMap.put("user", user);
        hashMap.put("school", school);
        hashMap.put("students", studentTemplateList);
        // 发送到上级服务
        String s = HttpClientUtil.doPost(portUrl + "vision/receive/addStudents", hashMap);
        Result result = JSON.parseObject(s, Result.class);
        if (result == null) {
            return Result.builder().code(500).msg("省级同步失败!").build();
        }
        System.out.println("result = " + result);
        // 本地开始添加学生
        int size = 0;
        if (result.getCode() == 200) {
            List<AddStudentParam> addStudentParam = JSON.parseArray(JSON.toJSONString(result.getData()), AddStudentParam.class);
            size = studentService.insertList(super.getUserName(),super.getUserId(), Long.valueOf(super.getSchoolId()), super.getStudentTable(), addStudentParam);
            return Result.builder().code(HttpStatus.OK.value()).msg(HttpStatus.OK.getReasonPhrase())
                    .data("导入了" + size + "条数据!").build();
        }

        return Result.builder().code(500).msg(result.getMsg()).build();
    }

    @GetMapping("exportStudentXls")
    @ApiOperation(value = "导出学生信息表", notes = "导出")
    public void exportStudentXls(Student student) throws IOException {
        super.response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        super.response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("学生信息表", "UTF-8").replaceAll("\\+", "%20");
        super.response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        if (super.getUserRole() != null && !super.getUserRole().equals("5")) {
            throw new RuntimeException("权限不足,您不是学校管理员!");
        }
        // 添加表名
        //studentArchives.setTableName(super.getStudentTable());
        student.setSSchoolId(Long.valueOf(super.getSchoolId()));
        List<ExportStudentTemplate> studentList = studentService.queryByPageExport(student);
        //studentList.forEach(System.out::println);
        EasyExcel.write(super.response.getOutputStream())
                .head(ExportStudentTemplate.class)
                .excelType(ExcelTypeEnum.XLSX)
                .sheet("工作表")
                .doWrite(studentList);
    }

    @GetMapping("downloadTemplate")
    @ApiOperation(value = "下载学生信息表模板", notes = "下载模板")
    public void downloadTemplate() throws IOException {
        super.response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        super.response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("学生信息表模板", "UTF-8").replaceAll("\\+", "%20");
        super.response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xls");

        String templateFileName = Thread.currentThread().getContextClassLoader().getResource("").getPath() + "templates/StudentTemplate.xls";
        // 传输文件
        FileInputStream fis = null;
        ServletOutputStream outputStream = null;
        try {
            fis = new FileInputStream(templateFileName);
            outputStream = response.getOutputStream();
            byte[] b = new byte[2048];
            int i = 0;
            while ((i = fis.read(b)) != -1) {
                outputStream.write(b, 0, i);
            }
        }catch (Exception e) {
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json");
            response.getWriter().write(JSONObject.toJSONString( Result.builder().code(500).msg("下载失败!").build()));
        }finally {
            outputStream.close();
            fis.close();
        }
    }

    @GetMapping("prints")
    @ApiOperation(value = "打印选中的学生二维码", notes = "打印多个二维码")
    public Result printStudents(Integer number, Long[] studentIds) {
        List<Student> arrayList = new ArrayList<>();
        if (studentIds == null){
            return Result.builder().code(500).msg("没有选中任何学生!").build();
        }
        for (Long id : studentIds) {
            Student student1 = studentService.queryById(id);
            if (student1 != null){
                String sIdCard = student1.getSIdCard();
                File file = new File(qrcodePath);
                if (!file.exists()) {
                    file.mkdirs();
                }
                String codePath = qrcodePath + sIdCard + ".jpg";
                // 生成二维码
                ZxingUtils.getQRCodeImge(String.valueOf(student1.getSStudentId()), 200, codePath);
                // 添加图片网络地址
                student1.setTableName("/oss/qrcode/" + sIdCard + ".jpg");
                arrayList.add(student1);
            }
        }
        // 合并图片, 每6张合成一张
        List<List<Student>> lists = MergePdfFiles.mySubList(arrayList);
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg(HttpStatus.OK.getReasonPhrase())
                .data(lists)
                .build();
    }

}

